<?php

require_once('_Core.php');

function phptal_tales_image($pSrc, $pNoThrow){
    $src = trim($pSrc);
    return '$ctx->this->objectRender(array(\'Type.slug\' => \'image\', \'slug\' => '.PHPTAL_Php_TalesInternal::string($src, $pNoThrow).'), \'view\')';
}
/*
class SilkCore_ImageMeta_Alt extends Silk_Module_Type_Meta {

    public function getName(){
	return 'Alternative';
    }

    public function getInputType(){
	return Silk::INPUT_TEXT;
    }
}

class SilkCore_ImageMeta_Class extends Silk_Module_Type_Meta {

    public function getName(){
	return 'CSS Class';
    }

    public function getInputType(){
	return Silk::INPUT_TEXT;
    }
}

class SilkCore_ImageMeta_File extends Silk_Module_Type_Meta {

    public function getName(){
	return 'Image File';
    }

    public function getInputType(){
	return Silk::INPUT_FILE;
    }
}*/

class SilkCore_Type_Image extends SilkCore_Type_Base {

//     public function __construct(){
// 	$this->_meta = array(
// 	    new SilkCore_ImageMeta_Alt(),
// 	    new SilkCore_ImageMeta_Class(),
// 	    new SilkCore_ImageMeta_File()
// 	);
//     }

    public function init(){
	Silk::RegisterCallback('object-post-save', array($this, 'postSave'));
    }

    public function getName(){
	return 'Image';
    }

    public function getSlug(){
	return 'image';
    }

    public function getDescription(){
	return 'Image';
    }

    /* Hook Callbacks */

    public function postSave(Silk_Object $pObject){
	Silk::debug('SilkCore_Type_Image.postSave: Hook object type = ' . $pObject->getModuleType()->getName());
	if ($pObject->getModuleType()->getName() == $this->getName()){
	    list($imagepath, $mimetype) = Silk::ReceiveFile('image_upload');

	    if ($imagepath){
		$path_parts = pathinfo($imagepath);
		$pObject->content = $path_parts['basename'];
		$pObject->mimetype = $mimetype;
		$pObject->save();
	    }
	}
    }

    /* Actions */

    public function render(Silk_Object $pImage=null, $pAction=null, array $pVars=array()){
	if ($pAction instanceof Silk_Template)
	    return parent::render($pImage, $pAction, $pVars);
	else if ($pAction){
	    $view = $this->prepare($pImage, $pVars);

	    $action = strtolower($pAction);

	    logdebug("SilkCore_Type_Image.render: Calling action - $action");

	    switch ($action){
		case 'admin':
		    return $this->_admin($view);
		case 'view':
		    return $this->_view($view, $pImage);
		case 'create':
		    return $this->_create($view, $pImage);
		case 'edit':
		    return $this->_edit($view, $pImage);
		case 'delete':
		    return $this->_delete($view, $pImage);
		case 'thumbnail':
		    return $this->_thumbnail($view, $pImage, $pVars);
		case 'scaleh':
		    return $this->_scale($view, $pImage, $pVars, 'h');
		case 'scalev':
		    return $this->_scale($view, $pImage, $pVars, 'v');
	    }

	} else {
	    $view = $this->prepare($pImage, $pVars);
	    return $this->renderString($view, $pImage->content);
	}
    }

    protected function prepare(Silk_Object $pImage=null, array $pVars){
	$view = $this->getViewEngine();

	if ($pImage){
	    $view->assign('object', $pImage);
	}
	foreach ($pVars as $key => $val)
	    $view->assign($key, $val);



	return $view;
    }

    protected function _thumbnail(Zend_View_Interface $pView, Silk_Object $pImage, array $pVars){
	logdebug('SilkCore_Type_Image._thumbnail: Called with vars - ' . logobject($pVars));

	if (array_keys_exist(array('width', 'height'), $pVars, true)){
	    $width = $pVars['width'];
	    $height = $pVars['height'];
	} else if (array_key_exists('width', $pVars)){
	    $width = $height = $pVars['width'];
	} else if (array_key_exist('height', $pVars)){
	    $height = $width = $pVars['height'];
	}

	if (array_key_exists('aratio', $pVars))
	    $aratio = $pVars['aratio'];
	else
	    $aratio = '1:1';

	$image = $this->getThumbnail($pImage, $width, $height, $aratio);

	header("Content-type: image/jpeg");
	header("ETag: " . md5($image->path));
	header("Cache-Control: public");
// 	header("Expires: " . gmdate('D, d M Y H:i:s', time() + (60 * 60 * 60) . ' GMT'));
	header("Content-Transfer-Encoding: binary");

	$image->stream();
    }

    protected function _scale(Zend_View_Interface $pView, Silk_Object $pImage, array $pVars, $pMode){

	logdebug('SilkCore_Type_Image._scale: Called with vars - ' . logobject($pVars));
	if (array_key_exists('max', $pVars)){
	    $max = $pVars['max'];
	    if ($pMode == 'h')
		$image = $this->getScaledH($pImage, $max);
	    else if ($pMode == 'v')
		$image = $this->getScaledV($pImage, $max);

	    header("Content-type: image/jpeg");
	    header("ETag: " . md5($image->path));
	    header("Cache-Control: public");
// 	    header("Expires: " . gmdate('D, d M Y H:i:s', time() + (60 * 60 * 60)) . ' GMT'));
	    header("Content-Transfer-Encoding: binary");

	    $image->stream();
	} else
	    throw new Silk_Exception('Maximum size parameter is required');
    }

    protected function _view(Zend_View_Interface $pView, Silk_Object $pImage){
	return '<img src="' . $this->getImageUrl($pImage) . '"/>';
    }

    protected function _create(Zend_View_Interface $pView, Silk_Object $pImage){

	$pView->this->appendStylesheet($this, 'css/core.manage.css');
	$pView->this->appendScript($this, 'js/core.manage.js');
	return $this->renderTemplate($pView, 'edit-image');

    }

    protected function _edit(Zend_View_Interface $pView, Silk_Object $pImage){

	$pView->this->appendStylesheet($this, 'css/core.manage.css');
	$pView->this->appendScript($this, 'js/core.manage.js');
	return $this->renderTemplate($pView, 'edit-image');

    }

    protected function _delete(Zend_View_Interface $pView, Silk_Object $pImage){

	$pView->this->appendStylesheet($this, 'css/core.manage.css');
	return $this->renderTemplate($pView, 'delete-image');

    }

    protected function _admin(Zend_View_Interface $pView){
	if (array_key_exists('sort', $_REQUEST)){
	    $sort = $_REQUEST['sort'];
	} else
	    $sort = 'object_id';

	if (array_key_exists('order', $_REQUEST)){
	    $order = $_REQUEST['order'];
	} else
	    $order = 'ASC';

	if (array_key_exists('limit', $_REQUEST)){
	    $limit = $_REQUEST['limit'];
	} else
	    $limit = 50;

	if (array_key_exists('page', $_REQUEST)){
	    $page = $_REQUEST['page'];
	} else
	    $page = 1;

	$paginator = Silk::getObjectPaginator($this->getSlug(), array(), $sort, $order);

	$paginator->setItemCountPerPage($limit);
	$paginator->setCurrentPageNumber($page);

	$Types = new Silk_Types();
	$type = $Types->fetchBySlug($this->getSlug(), true);

	$pView->moduletype = $this;
	$pView->type = $type;

	$pView->images = $paginator;
	$pView->limit = $limit;
	$pView->sort  = $sort;
	$pView->order = $order;
	$pView->this->appendStylesheet($this, 'css/core.manage.css');
	return $this->renderTemplate($pView, 'image-admin');
    }

    protected function getScaledH($pObject, $pMax){
	$cached_file = Silk::get('cachedir') . '/image/' . $pObject->object_id . '_sch_' . $pMax . '.jpg';
	if (file_exists($cached_file)){
	    $image = new FP_Image($cached_file);
	    return $image;
	} else {

	    $file = $this->getImagePath($pObject);
	    $image = new FP_Image($file);

	    if ($image->width > $pMax){
		logdebug("SilkCore_Type_Image.getScaledH: Scaling image {$pObject->object_id} to $pMax");
		$scaled = new FP_Image_Scale($image, $pMax, FP_Image_Scale::HORIZONTAL, array(
		    'destination' => $cached_file
		));
		return $scaled;
	    } else  {
		return $image;
	    }
	}
    }

    protected function getScaledV($pObject, $pMax){
	$cached_file = Silk::get('cachedir') . '/image/' . $pObject->object_id . '_scv_' . $pMax . '.jpg';
	if (file_exists($cached_file)){
	    $image = new FP_Image($cached_file);
	    return $image;
	} else {

	    $file = $this->getImagePath($pObject);
	    $image = new FP_Image($file);

	    if ($image->width > $pMax){
		$scaled = new FP_Image_Scale($image, $pMax, FP_Image_Scale::VERTICAL, array(
		    'destination' => $cached_file
		));
		return $scaled;
	    } else
		return $image;
	}
    }

    protected function getThumbnail($pObject, $pWidth, $pHeight, $pAspectRatio){
	$cached_file = Silk::get('cachedir') . '/image/' . $pObject->object_id . '_th_' . $pWidth . '_' . $pHeight . '_' . preg_replace('/:/', '_', $pAspectRatio) . '.jpg';
	if (file_exists($cached_file)){
	    $image = new FP_Image($cached_file);
	    return $image;
	} else {

	    $file = $this->getImagePath($pObject);

	    $thumb = new FP_Image_Thumbnail($file, $pWidth, $pHeight, $pAspectRatio, array(
		'destination' => $cached_file
	    ));
	    return $thumb;
	}
    }

    protected function dataSupported(){
	if (Silk::getBrowserName() == 'Internet Explorer' && Silk::getBrowserVersion() < 8)
	    return false;
	return true;
    }

    /* MAGIC METHODS */

    public function getImageUrl($pObject){
	return Silk::get('uploads') . '/' . $pObject->content;
    }

    public function getImagePath($pObject){
	return Silk::get('uploadsdir') . '/' . $pObject->content;
    }

    public function thumbnail($pObject, array $pArgs=array()){
	if (count($pArgs) >= 2){
	    $width = $pArgs[0];
	    $height = $pArgs[1];

	    if (count($pArgs) == 3)
		$aratio =-$pArgs[2];
	    else
		$aratio = '1:1';

	    $alt = $pObject->name;
	    $fallback_img = '<img src="' . Silk::url('/object/' . $pObject->object_id . '/thumbnail?width=' . $width . '&height=' . $height . '&aratio=' . $aratio) . '" alt="' . $alt .'"/>';
	    if (!$this->dataSupported()){
		return $fallback_img;
	    } else {
		$image = $this->getThumbnail($pObject, $width, $height, $aratio);

		$data = file_get_contents($image->path);
		$data = base64_encode($data);
		$img = '<img src="data:image/jpeg;base64,' . $data .'" alt="' . $alt .'"/>';
		return $img;

	    }
	} else
	    throw new Silk_Exception('width and height parameters required');
    }

    public function scaledH($pObject, array $pArgs=array()){
	if (count($pArgs) > 0){
	    $max = $pArgs[0];

	    $alt = $pObject->name;
	    $fallback_img = '<img src="' . Silk::url('/object/' . $pObject->object_id . '/scaleh?max=' . $max) . '" alt="' . $alt .'"/>';
	    if (!$this->dataSupported()){
		return $fallback_img;
	    } else {
		$image = $this->getScaledH($pObject, $max);

		$data = file_get_contents($image->path);
		$data = base64_encode($data);
		$img = '<img src="data:image/jpeg;base64,' . $data .'" alt="' . $alt .'"/>';
		return $img;

	    }
	} else
	    throw new Silk_Exception('Max width parameter required');
    }

    public function scaledV($pObject, array $pArgs=array()){
	if (count($pArgs) > 0){
	    $max = $pArgs[0];

	    $alt = $pObject->name;
	    $fallback_img = '<img src="' . Silk::url('/object/' . $pObject->object_id . '/scalev?max=' . $max) . '" alt="' . $alt .'"/>';
	    if (!$this->dataSupported()){
		return $fallback_img;
	    } else {
		$image = $this->getScaledV($pObject, $max);

		$data = file_get_contents($image->path);
		$data = base64_encode($data);
		$img = '<img src="data:image/jpeg;base64,' . $data .'" alt="' . $alt .'"/>';
		return $img;

	    }
	} else
	    throw new Silk_Exception('Max width parameter required');
    }
}

?>